package com.wqnmdb.im.service.mongo;

import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * MongodbService
 * description:
 *
 * @author wangxin
 * @version v1.0
 * @copy wangxin
 */
@Slf4j
@Service
public class MongoService {
	
	@Autowired
	private MongoTemplate mongoTemplate;

	/**
	 * 查询
	 * @param query
	 * @param cls
	 * @param <T>
	 * @return
	 */
	public <T> List<T> find(Query query, Class<T> cls) {
		return mongoTemplate.find(query, cls);
	}

    /**
     * 查询
     * @param query
     * @param cls
     * @param <T>
     * @return
     */
    public <T> List<T> find(Query query, Class<T> cls, String collectionName) {
        return mongoTemplate.find(query, cls, collectionName);
    }

	/**
	 * 查找一个
	 * @param query
	 * @param cls
	 * @param <T>
	 * @return
	 */
	public <T> T findOne(Query query, Class<T> cls) {
		return mongoTemplate.findOne(query, cls);
	}

    /**
     * 查找一个
     * @param query
     * @param cls
     * @param <T>
     * @return
     */
    public <T> T findOne(Query query, Class<T> cls, String collectionName) {
        return mongoTemplate.findOne(query, cls, collectionName);
    }

    /**
     * 根据ID查找
     * @param id
     * @param cls
     * @return
     */
    public <T> T findById(Object id,Class<T> cls) {
        return mongoTemplate.findById(id, cls);
    }

    /**
     * 根据ID查找
     * @param id
     * @param cls
     * @return
     */
    public <T> T findById(Object id,Class<T> cls, String collectionName) {
        return mongoTemplate.findById(id, cls, collectionName);
    }


    /**
	 * 更新
	 * @param query
	 * @param update
	 * @param cls
	 */
	public <T> T findAndModify(Query query, Update update, Class<T> cls) {
        return mongoTemplate.findAndModify(query, update, FindAndModifyOptions.options().returnNew(true), cls);
    }

	public UpdateResult updateFirst(Query query, Update update, Class<?> cls) {
		return mongoTemplate.updateFirst(query, update, cls);
	}

    public UpdateResult updateFirst(Query query, Update update, Class<?> cls, String collectionName) {
        return mongoTemplate.updateFirst(query, update, cls, collectionName);
    }
	
	public UpdateResult updateMulti(Query query, Update update, Class<?> cls) {
        return mongoTemplate.updateMulti(query, update, cls);
    }

    public UpdateResult updateMulti(Query query, Update update, Class<?> cls, String collectionName) {
        return mongoTemplate.updateMulti(query, update, cls, collectionName);
    }

	public UpdateResult upsert(Query query, Update update, Class<?> cls) {
		return mongoTemplate.upsert(query, update, cls);
	}
	
	/**
	 * 删除
	 * @param query
	 * @param cls
	 * @param collectionName
	 */
	public <T> void remove(Query query, Class<T> cls, String collectionName) {
        mongoTemplate.findAndRemove(query, cls,collectionName);
    }
	public <T> void remove(Query query, Class<T> cls) {
		mongoTemplate.remove(query, cls);
	}

	/**
	 * 插入
	 * @param entity
	 */
	public <T> T insert(T entity) {
        T insertResult = mongoTemplate.insert(entity);
        return insertResult;
	}

    /**
     * 插入
     * @param entity
     * @param collectionName
     */
    public <T> T insert(T entity, String collectionName) {
        T insertResult = mongoTemplate.insert(entity, collectionName);
        return insertResult;
    }

	/**
     * 保存
     * @param entity
     * @return
     */
    public <T> T save(T entity) {
        T saveResult = mongoTemplate.save(entity);
        return saveResult;
    }  

    /**
     * 分页
     * @param mongoPage
     * @param query
     * @param cls
     * @return
     */
	public <T> MongoPage<T> findPage(MongoPage<T> mongoPage, Query query, Class<T> cls, String collectionName){
		long count = this.count(query, cls, collectionName);
		mongoPage.setTotalCount(count);
		query.skip(mongoPage.getFirst()).limit(mongoPage.getPageSize());
		List<T> result = this.find(query, cls, collectionName);
		mongoPage.setResult(result);
		return mongoPage;
	}
    
    /**
     * 统计总数
     * @param query
     * @param cls
     * @return
     */
    public <T> long count(Query query, Class<T> cls){
        return mongoTemplate.count(query,cls);  
    }

    /**
     * 统计总数
     * @param query
     * @param cls
     * @return
     */
    public <T> long count(Query query, Class<T> cls, String collectionName){
        return mongoTemplate.count(query,cls,collectionName);
    }

	/**
	 * 执行指令~
	 * @param jsonCommand
	 * @return
	 */
	public Document executeCommand(String jsonCommand){
    	Document document =  mongoTemplate.executeCommand(jsonCommand);
    	return document;
	}

}
